/*M
 * Module-Name : mittel.c
 *
 * Purpose     : Print Bundesliga tips average values.
 *
 * Created     : ott 1993/08/15
 *
 * Updated     : ott 1993/09/02 check for duplicate tips
 *               xxx yyyy/mm/dd reason
 *
 * Copyright (c) 1993 OTT GmbH Munich, Germany. All rights reserved.
 *
 * $Log: mittel.c,v $
 * Revision 1.1  1995/07/23  18:32:44  i9750d
 * Initial revision
 *
 * Revision 1.2  1994/10/09  12:40:18  ott
 * ott: increased length of input-line
 *
 * Revision 1.1  1994/08/20  12:43:19  ott
 * Initial revision
 *
 */

/*--------------------------------------------- Include-Files -----------*/

#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#include <string.h>
#include <memory.h>
#include <stdlib.h>

#include "libbtm.h"

#define L_MAX		128	/* maxlen of input line */
#define N_TEAM		18	/* number of teams */

#define M_TEAM		struct MittelTeamList

M_TEAM
{
	int	vmin;			/* lowest pos */
	int	vmax;			/* highest pos */
	int	sum;			/* sum of all tips */
	int	rank;			/* computed position */
	int	tips [N_TEAM];
};

/*--------------------------------------------- Function Definitions ----*/

static void	ReadInFile (char *);
static void	NewTn (char *, char *);
static void	ComputeList (void);
static void	PrintList (void);
static char *	ReadLine (FILE *);

/*--------------------------------------------- Extern References -------*/

/*--------------------------------------------- Static References -------*/

static char *	Pgm;
static char	tabfile [] = "aktuell.btm";
static char	InFile [] = "tips.btm";
static char	EndStr [] = "DATEN ENDE";

static char	line [L_MAX + 1];

static M_TEAM	team [N_TEAM];
static int	SumTab [N_TEAM];
static int	IdxTab [N_TEAM];

static int	n_tn;
static int	gentip;

/*
 * messages
 */

static char	*M_Opn = "%s: kann Datei '%s' nicht oeffnen (%s)\n";
static char	*M_Eof = "%s: unerwartetes EOF in Datei '%s'\n";
static char	*M_Lin = "%s: ungueltige Zeile '%s'\n";
static char	*M_TEr = "tn '%s': ungueltiger Tip '%s'\n";
static char	*M_TIn = "tn '%s': ungueltiger Tip %d\n";
static char	*M_Tip = "tn '%s': %d Tips fuer Platz %d\n";

static S_BTM	btm;

/*--------------------------------------------- Global References -------*/

/*--------------------------------------------- Functions ---------------*/

/*F
 * Function-Name : void main (argc,argv)
 *
 * Parameters    : int argc - argument count
 *                 char *argv [] - argument strings
 *
 * Return-Values : none
 *
 * Purpose       : usage: mittel
 */

int
main (int argc, char **argv)
{
  Pgm = argv [0];

  while (--argc > 0)
  {
      ++argv;

      if (strcmp (*argv, "-g") == 0)
      {
          gentip = 1;
      }
  }

	if (lb_read_tabfile (tabfile, &btm) != 0)
		return 1;

  ReadInFile (InFile);
  ComputeList ();
  PrintList ();

  return 0;
}

/*-----------------------------------------------------------------------*/

/*F
 * Function-Name : static void ReadInFile (s)
 *
 * Parameters    : char *s - filename
 *
 * Return-Values : none
 *
 * Purpose       : Read the input file.
 */

static void
ReadInFile (char *s)
{
  int  i;
  FILE *fp;
  char *p;
  char *q;

  if ((fp = fopen (s, "r")) == NULL)
  {
      (void) fprintf (stderr, M_Opn, Pgm, s, sys_errlist [errno]);
      (void) exit (1);
  }

  /*
   * Skip the first 2 data lines, we don't need them.
   */

  for (i = 0; i < 2; ++i)
  {
      if (ReadLine (fp) == NULL)
      {
          (void) fprintf (stderr, M_Eof, Pgm, s);
          (void) exit (1);
      }
  }

  /*
   * Following lines have names and tips, format:
   * name       xxyyzz... meaning team 1 set to pos xx, team 2 to yy etc
   */

  for (;;)
  {
      if ((p = ReadLine (fp)) == NULL)
          break;

	if (strcmp (p, EndStr) == 0)
		break;

      if ((q = strrchr (p, ' ')) == NULL)
      {
          (void) fprintf (stderr, M_Lin, Pgm, p);
          (void) exit (1);
      }

      *q++ = 0x00;

      if (strncmp (p, "%% ", 3) != 0)
      {
          (void) NewTn (p, q);
          ++n_tn;
      }
  }

  (void) fclose (fp);
}

/*-----------------------------------------------------------------------*/

/*F
 * Function-Name : static void NewTn (name,tip)
 *
 * Parameters    : char *name - user's name
 *                 char *tip  - user's tip as digit string
 *
 * Return-Values : none
 *
 * Purpose       : Add an user's tip to sums.
 */

static void
NewTn (char *name, char *tip)
{
  int i, j;
  int tip_made [N_TEAM];

  char *p;

  if ((p = strrchr (name, ' ')) != NULL)
  {
      while (*p <= ' ')
      {
          *p-- = 0x00;
      }
  }

  for (i = 0; i < N_TEAM; ++i)
  {
      tip_made [i] = 0;
  }

  for (i = 0, p = tip; i < N_TEAM; ++i, p += 2)
  {
      if (sscanf (p, "%2d", &j) != 1)
      {
          (void) fprintf (stderr, M_TEr, name, tip);
          (void) exit (1);
      }

      if ((j < 1) || (j > N_TEAM))
      {
          (void) fprintf (stderr, M_TIn, name, j);
          (void) exit (1);
      }

      team [i].sum += j;
      ++(team [i].tips [j - 1]);
      ++(tip_made [j - 1]);

      if (j < team [i].vmin)
      {
          team [i].vmin = j;
      }

      if (j > team [i].vmax)
      {
          team [i].vmax = j;
      }
  }

  for (i = 0; i < N_TEAM; ++i)
  {
      if (tip_made [i] != 1)
      {
          (void) fprintf (stderr, M_Tip, name, tip_made [i], i + 1);
      }
  }
}

/*-----------------------------------------------------------------------*/

/*F
 * Function-Name : static void ComputeList ()
 *
 * Parameters    : none
 *
 * Return-Values : none
 *
 * Purpose       : Compute the list.
 */

static void
ComputeList (void)
{
  int i, j, k;

  for (i = 0; i < N_TEAM; ++i)
  {
      SumTab [i] = team [i].sum;
      IdxTab [i] = i;
  }

  /*
   * A bubble-sort puts the table in the right order.
   */

  for (i = 0; i < (N_TEAM - 1); ++i)
  {
      for (j = i + 1; j < N_TEAM; ++j)
      {
          if (SumTab [j] < SumTab [i])
          {
              k = SumTab [i];
              SumTab [i] = SumTab [j];
              SumTab [j] = k;
              k = IdxTab [i];
              IdxTab [i] = IdxTab [j];
              IdxTab [j] = k;
          }
      }
  }
}

/*-----------------------------------------------------------------------*/

/*F
 * Function-Name : static void PrintList ()
 *
 * Parameters    : none
 *
 * Return-Values : none
 *
 * Purpose       : Print table with average values.
 */

static void
PrintList (void)
{
  int i, j, k;
  int lastsum = -1;
  int lastrank = 0;

  (void) printf ("%d Tips\n\n", n_tn);

  (void) printf ("Platz Verein                      Summe  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18\n\n");

  for (i = 0; i < N_TEAM; ++i)
  {
      j = IdxTab [i];

      if (lastsum != team [j].sum)
      {
          (void) printf ("%4d. ", i + 1);
          lastrank = i + 1;
      }
      else
      {
          (void) printf ("      ");
      }

      team [j].rank = lastrank;
      lastsum = team [j].sum;

      (void) printf ("%-28s %4d", btm.tn_t [j], team [j].sum);

      for (k = 0; k < N_TEAM; ++k)
      {
          if (team [j].tips [k])
          {
              (void) printf ("%3d", team [j].tips [k]);
          }
          else
          {
              (void) printf ("  -");
          }
      }

      (void) printf ("\n");
  }

  if (gentip != 0)
  {
      (void) printf ("\n");
      (void) printf ("%%%% Mittelwert       ");

      for (i = 0; i < N_TEAM; ++i)
      {
          (void) printf ("%02d", team [i].rank);
      }

      (void) printf ("\n");
  }
}

/*-----------------------------------------------------------------------*/

/*F
 * Function-Name : static char *ReadLine (fp)
 *
 * Parameters    : FILE *fp - filepointer to use
 *
 * Return-Values : NULL on EOF
 *                 else pointer to non-empty, non-comment line
 *
 * Purpose       : Read a significant line from a file.
 */

static char *
ReadLine (FILE *fp)
{
	char *p;

	while (fgets (line, L_MAX, fp) != NULL)
	{
		if ((p = strchr (line, '\n')) != NULL)
			*p = 0x00;

		if ((line [0] != '#') && (line [0] != 0x00))
			return (line);
	}

	return (NULL);
}

/*-----------------------------------------------------------------------*/

/*F
 * Function-Name : static char *ReadLine (fp)
 *
 * Parameters    : FILE *fp - filepointer to use
 *
 * Return-Values : NULL on EOF
 *                 else pointer to non-empty, non-comment line
 *
 * Purpose       : Read a significant line from a file.
 */

void
AddMsg (char *s)
{
	fprintf (stderr, "%s\n", s);
}

/*-----------------------------------------------------------------------*/

/* mittel.c */
